package com.zoshine.zzg.interceptor;

import com.zoshine.zzg.annotation.DisableLoginCheck;
import com.zoshine.zzg.constant.Session;
import com.zoshine.zzg.exception.AppException;
import com.zoshine.zzg.exception.ErrorMessage;
import org.springframework.context.annotation.Bean;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * 安全拦截器
 *
 * @author 贾俊峰
 * @time 2017/5/11 17:43
 */
public class SecurityInterceptor extends HandlerInterceptorAdapter {
    private static final String LOGIN_PAGE = "/login.html";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
            Object handler) throws Exception {

        HandlerMethod handlerMethod = (HandlerMethod) handler;

        // 判断方法所在Controller类上是否有DisableLoginCheck注解
        Class controller = handlerMethod.getBeanType();
        Annotation annotation = controller.getAnnotation(DisableLoginCheck.class);
        if (annotation != null) {
            return true;
        }

        // 判断方法上是否有DisableLoginCheck注解
        Method method = handlerMethod.getMethod();
        DisableLoginCheck disableLoginCheck = method.getAnnotation(DisableLoginCheck.class);
        if (disableLoginCheck != null) {
            return true;
        }

        HttpSession session = request.getSession();
        Object loginUser = session.getAttribute(Session.LOGIN_USER);
        if (loginUser == null) { // 犯人登录
            loginUser = session.getAttribute(Session.PRISONER_INFO);
        }
        if (loginUser == null) {
            // 判断本次请求是请求页面还是json
            RestController restController = (RestController) controller.getAnnotation(RestController.class);
            ResponseBody responseBody = method.getAnnotation(ResponseBody.class);

            if (restController == null) {
                if (responseBody == null) {
                    response.sendRedirect(LOGIN_PAGE);
                } else {
                    throw new AppException(ErrorMessage.NO_LOGIN);
                }
            } else {
                Class returnType = method.getReturnType();
                if (returnType.isInstance(Model.class)) {
                    response.sendRedirect(LOGIN_PAGE);
                } else {
                    throw new AppException(ErrorMessage.NO_LOGIN);
                }
            }
            return false;
        }
        return true;
    }

}

